package com.noble.glamour.ui.agora.act.video;

import android.graphics.Rect;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.faceunity.MRender;
import com.noble.glamour.R;
import com.noble.glamour.bean.center.user.detail.UserDetail;
import com.noble.glamour.bean.center.user.light.UserInfoLightweight;
import com.noble.glamour.module.logic.application.ModuleMgr;
import com.noble.glamour.module.logic.baseui.LoadingDialog;
import com.noble.glamour.module.logic.baseui.custom.CountDownTextView;
import com.noble.glamour.module.logic.invoke.Invoker;
import com.noble.glamour.module.logic.webserver.WebService;
import com.noble.glamour.module.logic.webserver.WebServiceConfig;
import com.noble.glamour.module.util.TimeUtil;
import com.noble.glamour.module.util.TimerUtil;
import com.noble.glamour.module.util.WebUtil;
import com.noble.glamour.ui.agora.act.base.RtcBaseActivity;
import com.noble.glamour.ui.agora.act.base.RtcWebPanel;
import com.noble.glamour.ui.agora.act.bean.ChatStatus;
import com.noble.glamour.ui.agora.manager.RtcMessageMgr;
import com.noble.glamour.ui.agora.beauty.ViewFaceBeautify;
import com.noble.glamour.ui.agora.model.AgoraConstant;
import com.noble.glamour.ui.agora.util.RtcJointChannel;
import com.noble.glamour.ui.agora.util.RtcSubUtil;
import com.noble.glamour.ui.agora.util.RtcTimerUtil;
import com.noble.glamour.ui.utils.NoDoubleClickListener;
import com.noble.library.image.ImageLoader;
import com.noble.library.log.PToast;
import com.noble.library.observe.Msg;
import com.noble.library.observe.MsgMgr;
import com.noble.library.observe.MsgType;
import com.noble.library.observe.PObserver;
import com.noble.library.view.CustomFrameLayout;

import java.util.HashMap;
import java.util.Map;

import io.agora.rtc.video.VideoCanvas;

/**
 * 视频通话
 * <p>
 * Created by Su on 2017/3/17.
 */
public class RtcVideoActivity extends RtcBaseActivity implements PObserver {
    private RelativeLayout rootView;
    private int lastHeight = 0;
    private LinearLayout msgTipsLayout;      // 钻石不足提示消息
    private CountDownTextView tipsCountDown; // 钻石不足提示倒计时
    private ChatStatus chatStatus;           // 聊天付费信息数据

    private FrameLayout remoteContainer;    // 远端容器
    private FrameLayout localContainer;     // 本地容器
    private SurfaceView remoteSurfaceV;     // 远端展示控件
    private SurfaceView localSurfaceV;      // 本地展示控件
    private CustomFrameLayout videoFrame;   // 本地视频开关状态
    private ImageView btnClose;             // 关闭本地视频
    private TextView connTips;              // 女性接通提示
    private boolean showRotary = false;     // 展示大转盘
    private LinearLayout rotaryPanel;       // H5大转盘
    private ViewFaceBeautify faceBeautify;  // 美颜View
    private RtcWebPanel webPanel;

    private UserDetail userDetail;          // 自己资料
    private LinearLayout chatLayout;
    private RtcVideoHeadPanel headPanel;
    private RtcVideoFooterPanel footerPanel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        rootView = (RelativeLayout) getLayoutInflater().inflate(R.layout.p1_chat_video, null);
        setContentView(rootView);
        initUIandEvent();
        addListener();
        addGlobalListener();
    }

    // ===================================== 初始化 ===================================================

    private void addListener() {
        if (RtcMessageMgr.getInstance().leaveChat()) {
            finish();
            PToast.showLong(getString(R.string.chat_tips_user_hangup));
            return;
        }
        MsgMgr.getInstance().attach(this);
    }


    private void addGlobalListener() {
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (isFinishing()) return;
                Rect r = new Rect();
                getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
                int screenHeight = getWindow().getDecorView().getRootView().getHeight();
                int heightDifference = screenHeight - r.bottom;

                //键盘收起,弹出
                if (heightDifference == 0 && lastHeight > 0) {
                    chatLayout.setTranslationY(0);
                    footerPanel.refreshLayout();
                } else if (heightDifference > 0) {
                    chatLayout.setTranslationY(-heightDifference);
                }
                lastHeight = heightDifference;
            }
        });
    }

    protected void initUIandEvent() {
        WebService.getInstance().StartWebServiceForSDCard();   // 启动WebService
        userDetail = ModuleMgr.getCenterMgr().getMyInfo();
        UserInfoLightweight infoLight = getIntent().getParcelableExtra(AgoraConstant.USER_LIGHT_INFO_KEY);

        // 远端视频容器
        remoteContainer = (FrameLayout) findViewById(R.id.video_remote);
        remoteSurfaceV = RtcJointChannel.getInstance().getRemoteSurfaceV();
        remoteContainer.setOnClickListener(listener);

        // 本地视频容器
        connTips = (TextView) findViewById(R.id.connect_tips);
        localContainer = (FrameLayout) findViewById(R.id.video_local);
        localContainer.setOnClickListener(listener);
        localSurfaceV = RtcJointChannel.getInstance().getLocalSurfaceV();
        RtcJointChannel.getInstance().setVideoContainer(remoteContainer, localContainer);

        // 美颜弹框
        faceBeautify = (ViewFaceBeautify) findViewById(R.id.chat_face_beauty);
        ModuleMgr.getRtcEnginMgr().setFaceUListener(faceBeautify);

        if (!userDetail.isMan()) { // 女性用户
            ImageView videoImg = (ImageView) findViewById(R.id.video_img);
            TextView videoTips = (TextView) findViewById(R.id.video_tips);
            videoImg.setVisibility(View.GONE);
            videoTips.setText(getString(R.string.chat_video_open_female));
        }

        // 本地视频功能按钮
        videoFrame = (CustomFrameLayout) findViewById(R.id.custom_video_local);
        btnClose = (ImageView) findViewById(R.id.btn_close_local);
        ImageView iv_head = (ImageView) findViewById(R.id.iv_head);
        ImageLoader.loadCircleAvatar(this, userDetail.getAvatar(), iv_head);
        if (userDetail.isMan()) {
            btnClose.setVisibility(View.VISIBLE);
            btnClose.setOnClickListener(listener);
            findViewById(R.id.btn_open_video).setOnClickListener(listener);
            initCountDownTimer();// 倒计时控件
        }

        // 头部布局
        LinearLayout headLayout = (LinearLayout) findViewById(R.id.chat_head_panel);
        headPanel = new RtcVideoHeadPanel(this, isOpenCamera(), infoLight);
        headLayout.addView(headPanel.getContentView());
        headPanel.setPanelListener(new RtcVideoHeadPanel.PanelListener() {
            @Override
            public void onPanelClick(View v) {
                if (checkOverLaysPermission())
                    ModuleMgr.getRtcEnginMgr().startRtcFloatService();
            }
        });

        verControl();
        initVideoContainer();
        ModuleMgr.getRtcEnginMgr().setVideoChat(true);// 设置用户视频聊天状态
        ModuleMgr.getRtcEnginMgr().initPropList();    // 道具列表

        if (!config().mHasJoin) {
            ModuleMgr.getRtcEnginMgr().getBugSteps().add("步骤2：准备连接视频通道" + TimeUtil.getFormatTimeChatTip(ModuleMgr.getAppMgr().getTime()));
            ModuleMgr.getRtcEnginMgr().joinChannel(config().mChannel);
            config().mHasJoin = true;
        }
    }

    /**
     * 版本控制界面展示
     */
    private void verControl() {
        rotaryPanel = (LinearLayout) findViewById(R.id.chat_rotary_panel);
        chatLayout = (LinearLayout) findViewById(R.id.chat_faction_panel);

        if (config().msgVer < AgoraConstant.RTC_MSG_VER) {
            rotaryPanel.setVisibility(View.GONE);
            chatLayout.setVisibility(View.GONE);
            return;
        }

        // H5容器
        HashMap<String, Object> rotaryParams = new HashMap<>();
        rotaryParams.put("view_type", 1);
        String rotaryUrl = WebUtil.jointUrl(WebServiceConfig.reqVideoWebRotary.getUrl(), rotaryParams);
        webPanel = new RtcWebPanel(this, rotaryUrl);
        rotaryPanel.addView(webPanel.getContentView());

        // 底部功能按钮
        footerPanel = new RtcVideoFooterPanel(this);
        chatLayout.addView(footerPanel.getContentView());
        footerPanel.setFooterPanelListener(new RtcVideoFooterPanel.FooterPanelListener() {
            @Override
            public void onFooterbtnClick(View v) {
                switchH5Panel();
            }
        });
    }

    private void switchH5Panel() {
        // 关闭大转盘
        try {
            if (showRotary) {
                showRotary = false;
                footerPanel.chatEnable(true);
                Invoker.getInstance().switchH5JSCMD(0, config().mOtherId);
                videoFrame.setVisibility(View.VISIBLE);
                return;
            }

            // 开启大转盘
            showRotary = true;
            footerPanel.chatEnable(false);
            Invoker.getInstance().switchH5JSCMD(1, config().mOtherId);
            videoFrame.setVisibility(View.GONE);
        } catch (Exception e) {
        }
    }

    private NoDoubleClickListener listener = new NoDoubleClickListener() {
        @Override
        public void onNoDoubleClick(View v) {
            switch (v.getId()) {
                case R.id.video_local:
                    if (userDetail.isMan())
                        btnClose.setVisibility(RtcJointChannel.getInstance().getSwitchVideo() ?
                                View.VISIBLE : View.GONE);
                    RtcJointChannel.getInstance().switchVideo();
                    break;

                case R.id.video_remote:
                    if (footerPanel == null) return;
                    footerPanel.refreshLayout();
                    break;

                case R.id.btn_open_video:   // 开启本地视频
                    openLocalVideo();
                    break;

                case R.id.btn_close_local:  // 关闭本地视频
                    closeLocalVideo();
                    break;
            }
        }
    };

    // ------------------------------ 视频相关 ------------------------------------

    private void initVideoContainer() {
        // 首次通信绑定己方视频容器
        if (RtcJointChannel.getInstance().getFirstVideo()) {
            setupLocalVideo();
            RtcJointChannel.getInstance().setFirstVideo(false);
            return;
        }

        // 男性用户
        if (userDetail.isMan()) {
            // 开启摄像头
            if (isOpenCamera()) {
                RtcJointChannel.getInstance().setSwitchVideo(true);
                videoFrame.show(R.id.rl_video_local_open);
                RtcJointChannel.getInstance().initSurfaceV();
                return;
            }

            // 关闭摄像头
            videoFrame.show(R.id.ll_local_video_close);
            RtcJointChannel.getInstance().setRemoteToRemote();
            return;
        }

        // 女性用户且对方开启了摄像头
        if (ModuleMgr.getRtcEnginMgr().getEngineConfig().mOpenCamera) {
            RtcJointChannel.getInstance().setSwitchVideo(true);
            onRemoteOpenVideo();
            return;
        }

        // 对方未开启
        videoFrame.show(R.id.ll_local_video_close);
        RtcJointChannel.getInstance().setLocalToRemote();
    }

    /**
     * 是否开启本地摄像头(男性用户)
     */
    private boolean isOpenCamera() {
        return config().mCamera == 1;
    }

    /**
     * 绑定远端视频容器
     */
    private void doRenderRemoteUi() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                RtcSubUtil.getInstance().startPicTime();   // 开启鉴黄图片上传轮询

                // 男性用户, 直接绑定远端视频
                if (userDetail.isMan()) {
                    RtcJointChannel.getInstance().setRemoteToRemote();
                    return;
                }

                // 女性用户
                setRemoteView();
            }
        });
    }

    private void setRemoteView() {
        videoFrame.show(R.id.rl_video_local_open);
        if (!RtcJointChannel.getInstance().getSwitchVideo()) {
            RtcJointChannel.getInstance().removeRemoteView();
            remoteContainer.removeAllViews();
            remoteContainer.addView(remoteSurfaceV);
        } else {
            RtcJointChannel.getInstance().removeRemoteView();
            localContainer.removeAllViews();
            localContainer.addView(remoteSurfaceV);
        }
        RtcJointChannel.getInstance().switchVideo();
    }

    /**
     * 绑定已方视频容器
     */
    private void setupLocalVideo() {
        ModuleMgr.getRtcEnginMgr().getRtcEngine().setupLocalVideo(new VideoCanvas(localSurfaceV, VideoCanvas.RENDER_MODE_HIDDEN, 0));

        // 女性用户首次大视频展示
        if (!userDetail.isMan()) {
            RtcJointChannel.getInstance().setSwitchVideo(true);
            remoteContainer.removeAllViews();
            RtcJointChannel.getInstance().removeLocalView();
            remoteContainer.addView(localSurfaceV);
            ModuleMgr.getRtcEnginMgr().preview(true, localSurfaceV);
            videoFrame.show(R.id.ll_local_video_close);
        }

        // 男性用户
        else {
            if (isOpenCamera()) {  // 首次开启本地视频
                videoFrame.show(R.id.rl_video_local_open);
                localContainer.removeAllViews();
                RtcJointChannel.getInstance().removeLocalView();
                localContainer.addView(localSurfaceV);
                ModuleMgr.getRtcEnginMgr().preview(true, localSurfaceV);
            } else {
                videoFrame.show(R.id.ll_local_video_close);
                ModuleMgr.getRtcEnginMgr().getRtcEngine().muteLocalVideoStream(true);
            }
        }
        RtcSubUtil.getInstance().setIntervalConfig(config().mIntervalFirstTime, config().mIntervalTime);
    }

    /**
     * 开启本地视频发送流(男性用户)
     */
    private void openLocalVideo() {
        headPanel.refreshCamera(false);
        videoFrame.show(R.id.rl_video_local_open);
        ModuleMgr.getRtcEnginMgr().getRtcEngine().muteLocalVideoStream(false);
        ModuleMgr.getRtcEnginMgr().getEngineConfig().mCamera = 1;

        TimerUtil.beginTime(new TimerUtil.CallBack() {
            @Override
            public void call() {
                localContainer.removeAllViews();
                remoteContainer.removeAllViews();
                RtcJointChannel.getInstance().removeLocalView();
                RtcJointChannel.getInstance().removeRemoteView();
                localContainer.addView(localSurfaceV);
                remoteContainer.addView(remoteSurfaceV);
                ModuleMgr.getRtcEnginMgr().preview(true, localSurfaceV);   // 开启本地视频预览
            }
        }, 200);
    }

    /**
     * 关闭本地视频发送流(男性用户)
     */
    private void closeLocalVideo() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                headPanel.refreshCamera(true);
                localContainer.removeAllViews();
                ModuleMgr.getRtcEnginMgr().preview(false, null);   // 关闭本地视频预览
                ModuleMgr.getRtcEnginMgr().getRtcEngine().muteLocalVideoStream(true);
                ModuleMgr.getRtcEnginMgr().getEngineConfig().mCamera = 2;
                videoFrame.show(R.id.ll_local_video_close);
            }
        });
    }

    /**
     * 远端关闭视频 (女性用户)
     */
    private void onRemoteCloseVideo() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                RtcSubUtil.getInstance().stopPicTime();   // 关闭鉴黄图片上传轮询
                // 此时大图展示本地，直接关闭
                if (RtcJointChannel.getInstance().getSwitchVideo()) {
                    localContainer.removeAllViews();
                    videoFrame.show(R.id.ll_local_video_close);
                    return;
                }

                // 此时小图展示本地, 切换到大图
                RtcJointChannel.getInstance().setSwitchVideo(true);
                remoteContainer.removeAllViews();
                localContainer.removeAllViews();
                RtcJointChannel.getInstance().removeLocalView();
                remoteContainer.addView(localSurfaceV);
                videoFrame.show(R.id.ll_local_video_close);
                ModuleMgr.getRtcEnginMgr().preview(true, localSurfaceV);
            }
        });
    }

    /**
     * 远端开启视频（女性用户）
     */
    private void onRemoteOpenVideo() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                RtcSubUtil.getInstance().startPicTime();   // 开启鉴黄图片上传轮询
                videoFrame.show(R.id.rl_video_local_open);
                // 此时小图展示本地
                if (!RtcJointChannel.getInstance().getSwitchVideo()) {
                    remoteContainer.removeAllViews();
                    RtcJointChannel.getInstance().removeRemoteView();
                    remoteContainer.addView(remoteSurfaceV);
                    return;
                }

                // 此时大图展示本地, 直接延迟切换视图
                TimerUtil.beginTime(new TimerUtil.CallBack() {
                    @Override
                    public void call() {
                        RtcJointChannel.getInstance().switchVideo();
                    }
                }, 100);
            }
        });
    }

    // ===================================== 本地计时统计 ===================================================
    private void initCountDownTimer() {
        msgTipsLayout = (LinearLayout) findViewById(R.id.msg_tips);
        tipsCountDown = (CountDownTextView) findViewById(R.id.tv_countDown);
        RtcTimerUtil.getInstance().addTimer(tipsCountDown);
        TextView tipsTxt = (TextView) findViewById(R.id.time_left_tips);

        // 女号都是邀请流程，扣费方全部为男方扣费
        if (!ModuleMgr.getCenterMgr().getMyInfo().isMan())
            tipsTxt.setText(getString(R.string.chat_tips_other_no_diamond));

        if (config().millisLeft > 0 && config().millisLeft <= AgoraConstant.CHAT_COST_PROMPT) {
            msgTipsLayout.setVisibility(View.VISIBLE);
            tipsCountDown.setCountDownTimes(config().millisLeft * 1000);
            tipsCountDown.start();
        }
    }

    private void refreshDiamond() {
        // 女性聊天不扣费
        if (!ModuleMgr.getCenterMgr().getMyInfo().isMan()) {
            return;
        }
        ModuleMgr.getCenterMgr().getMyInfo().setDiamand(chatStatus.getDiamondLeft());
    }

    /**
     * 通话状态消息
     */
    @Override
    public void onMessage(String key, Object value) {
        switch (key) {
            case MsgType.MT_Rtc_Chat_Status:
                Map<String, Object> data = (Map<String, Object>) value;
                switch ((int) data.get("type")) {
                    case 3:
                    case 4:     // 挂断
                        PToast.showShort(getString(R.string.chat_tips_user_hangup));
                        finish();
                        break;
                    default:
                        break;
                }
                break;

            case MsgType.MT_Rtc_Chat_Rotary:  // 女： 开始转动转盘
                int index = (int) value;
                if (showRotary) {
                    Invoker.getInstance().rotaryResultJSCMD(index);
                    return;
                }
                switchH5Panel();
                Invoker.getInstance().rotaryResultJSCMD(index);
                break;

            case MsgType.MT_Rtc_Chat_Close_Msg:
                finish();
                break;

            case MsgType.MT_Rtc_Chat_Connect_Suc:
                LoadingDialog.closeLoadingDialog();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        connTips.setVisibility(View.VISIBLE);
                    }
                });
                break;

            case MsgType.MT_Rtc_Chat_Video_Remote:
                doRenderRemoteUi();
                break;

            case MsgType.MT_Rtc_Chat_Remote_Status:
                if ((boolean) value) {
                    onRemoteCloseVideo();
                    return;
                }

                onRemoteOpenVideo();
                break;

            case MsgType.MT_Rtc_Check_Video_Chat:
                chatStatus = (ChatStatus) value;
                if (!userDetail.isMan())
                    headPanel.refreshEarn(chatStatus);
                refreshDiamond();
                break;

            case MsgType.MT_Rtc_Chat_Timer_Msg:
                if (!userDetail.isMan()) return;
                if ((int) value == AgoraConstant.TIMER_LAST_TIPS) {
                    msgTipsLayout.setVisibility(View.VISIBLE);
                    tipsCountDown.setCountDownTimes(config().millisLeft * 1000);
                    tipsCountDown.start();
                    return;
                }

                if ((int) value == AgoraConstant.TIMER_CHATING) {
                    if (config().mTimespan == AgoraConstant.CHAT_UPDATE_VIDEO_FIRST)
                        RtcSubUtil.getInstance().resetFirstUpload();
                }
                break;

            case MsgType.MT_Rtc_Chat_Send_Gift:
                headPanel.refreshAddBuddy();
                break;

            case MsgType.MT_Rtc_Rotary_Status:
                footerPanel.refreshRotary((boolean) value);
                break;

            case MsgType.MT_Chat_Can:
                if (ModuleMgr.getCenterMgr().getMyInfo().isMan() && !ModuleMgr.getCenterMgr().getMyInfo().isVip()) {//男
                    footerPanel.refreshChatBtn((Boolean) ((Msg) value).getData());
                }
                break;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (webPanel != null) {
            webPanel.getWebView().onResume();
            webPanel.getWebView().resumeTimers();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (webPanel != null) {
            webPanel.getWebView().onPause();
            webPanel.getWebView().pauseTimers();
        }
    }

    private void releaseWebView() {
        if (webPanel != null)
            webPanel.clearReference();
        if (rotaryPanel != null)
            rotaryPanel.removeAllViews();
        webPanel = null;
        rotaryPanel = null;
    }

    private void releaseView() {
        config().mHasJoin = false;
        WebService.getInstance().stop();
        MRender.destroy();
        RtcSubUtil.getInstance().release();
        RtcJointChannel.getInstance().releaseView();

        if (faceBeautify != null) {
            faceBeautify.setBeautifyInterface(null);
            ((ViewGroup) faceBeautify.getParent()).removeView(faceBeautify);
            faceBeautify = null;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseWebView();
    }

    @Override
    public void finish() {
        super.finish();
        LoadingDialog.closeLoadingDialog();
        MsgMgr.getInstance().detach(this);
        ModuleMgr.getRtcEnginMgr().setVideoChat(false);     // 视频中收发消息

        // 处于悬浮窗、跳到视频页面， 则只需释放本地Timer计时
        if (RtcJointChannel.getInstance().getFloatStatus()) {
            ModuleMgr.getRtcEnginMgr().releaseLocalTimer();
            return;
        }

        // 全部回收
        releaseView();
        ModuleMgr.getRtcEnginMgr().releaseAll();
        ModuleMgr.getRtcEnginMgr().bugFeedback();
    }
}
